package com.ass.elasticsearch.service;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.ass.elasticsearch.mapper.EasyEsBaseMapper;
import org.apache.commons.lang3.StringUtils;
import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.biz.SAPageInfo;
import org.dromara.easyes.core.conditions.index.LambdaEsIndexWrapper;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.dromara.easyes.core.core.Wrapper;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

public abstract class EasyEsBaseService<M, EasyEsMapper extends EasyEsBaseMapper<M>>{



    @Autowired
    protected EasyEsMapper easyEsMapper;


//    protected Class<ESMAPPER> currentMapperClass() {
//        return (Class<ESMAPPER>) ReflectionKit.(getClass(), 1);
//    }

    //sugar
    protected final boolean notBlank(CharSequence cs) {
        return StringUtils.isNotBlank(cs);
    }

    protected final boolean blank(CharSequence cs) {
        return StringUtils.isBlank(cs);
    }

    protected final boolean empty(Collection<?> coll) {
        return CollectionUtils.isEmpty(coll);
    }

    protected final boolean notEmpty(Collection<?> coll) {
        return CollectionUtils.isNotEmpty(coll);
    }

    protected final boolean equal(Object a, Object b) {
        return Objects.equals(a, b);
    }



    /**
     * 按条件取列表 条件为model值全等 给子类实现调用 不建议 这样写 因为我封装不出来 难过
     */
    public List<M> list(@Nullable M model) {
        return null;
    }




    /**
     * id in
     */
    public List<M> listInIds(Collection<? extends Serializable> idCollection) {
        if (CollectionUtils.isNotEmpty(idCollection)) {
            return easyEsMapper.selectBatchIds(idCollection);
        } else {
            return new ArrayList<>();
        }
    }


    /**
     * 按主键取一条
     */
    @Nullable
    public M oneById(@NotNull Serializable id) {
        return easyEsMapper.selectById(id);
    }


    /**
     * 新增一条
     * 注意：直接插入数据时，会自动创建索引，但会对String字段推断为TEXT，而不是 KEYWORD。
     */
//    @Transactional(rollbackFor = Exception.class)
    public boolean insert(@NotNull M model) {
        return easyEsMapper.insert(model) > 0;
    }

    /**
     * 批量新增
     */
    public boolean insertBatch(@NotNull List<M> models) {
        return easyEsMapper.insertBatch(models) > 0;
    }


    /**
     * 按主键修改一条
     */
//    @Transactional(rollbackFor = Exception.class)
    public boolean updateById(@NotNull M model) {
        return easyEsMapper.updateById(model) > 0;
    }


    /**
     * 按主键删一条
     */
//    @Transactional(rollbackFor = Exception.class)
    public <S extends Serializable> boolean deleteById(@NotNull S id) {
        return easyEsMapper.deleteById(id) >= 0;
    }




    /**
     * 创建索引 对应的实体 如果这个方法不适用 则去官网查看另外几种方法
     */
    public boolean createIndex(){
        return easyEsMapper.createIndex();
    }

    /**
     * @describe：根据当前mapper对应实体类信息及其注解配置生成索引信息，可指定索引名进行创建 适用于定时任务按日期创建索引场景
     * @author：李勇
     * @date：2025/11/6
     * @param indexName
     * @return：boolean
     */
    public boolean createIndex(String indexName){
        return easyEsMapper.createIndex(indexName);
    }



    /**
     * 创建索引 对应的实体 如果这个方法不适用 则去官网查看另外几种方法
     */
    public boolean deleteIndex(String indexName){
        return easyEsMapper.deleteIndex(indexName);
    }





    /**
     * 按条件取列表
     */
    protected final List<M> listWrapper(Wrapper wrapper) {
        return easyEsMapper.selectList(wrapper);
    }

    /**
     * 浅分页 物理翻页
     *
     * @param page    页码参数
     * @param wrapper 查询参数
     */
    protected final EsPageInfo<M> pageWrapper(EsPageInfo page, Wrapper<M> wrapper) {
        return easyEsMapper.pageQuery(wrapper,page.getPageNum(), page.getPageSize());
    }



    protected final SearchResponse scroll(SearchScrollRequest searchScrollRequest, RequestOptions requestOptions) throws IOException {
        //TODO 业务model替换SearchScrollRequest RequestOptions
        SearchScrollRequest a = new SearchScrollRequest();
        QueryBuilder query = SearchSourceBuilder.searchSource().query();
        return easyEsMapper.scroll(searchScrollRequest,requestOptions);
    }

    //这个排序只能使用主键排序 保证查询的数据准确性
    protected final SAPageInfo<M> pageSearchAfter(LambdaEsQueryWrapper<M> wrapper, SAPageInfo<M> saPageInfoParams){
        wrapper.size(saPageInfoParams.getPageSize());
        return easyEsMapper.searchAfterPage(wrapper, saPageInfoParams.getNextSearchAfter(), saPageInfoParams.getPageSize());
    }







}
